<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Query Task 3D</title>

<style>
html, body {
  margin: 0;
  padding: 0;
}

#optionsDiv {
  background-color: dimgray;
  color: white;
  z-index: 23;
  position: absolute;
  top: 0px;
  right: 0px;
  padding: 0px 0px 0px 10px;
  border-bottom-left-radius: 5px;
  max-width: 350px;
}
.esri-popup .esri-popup-header .esri-title {
  font-size: 18px;
  font-weight: bolder;
}
.esri-popup .esri-popup-body .esri-popup-content {
  font-size: 14px;
}

</style>

<link rel="stylesheet" href="https://js.arcgis.com/4.0beta3/esri/css/main.css">
<script src="https://js.arcgis.com/4.0beta3/"></script>

<script>
var map, view, qTask, params;

require([
  "esri/Map",
  "esri/views/SceneView",
  "esri/layers/GraphicsLayer",
  "esri/symbols/SimpleMarkerSymbol",
  "esri/symbols/SimpleLineSymbol",
  "esri/symbols/PointSymbol3D",
  "esri/symbols/ObjectSymbol3DLayer",
  "esri/tasks/QueryTask",
  "esri/tasks/support/Query",
  "esri/PopupTemplate",
  "dojo/_base/array",
  "dojo/dom",
  "dojo/on",
  "dojo/domReady!"
], function(
  Map, SceneView, GraphicsLayer, SimpleMarkerSymbol, SimpleLineSymbol, PointSymbol3D, ObjectSymbol3DLayer,
  QueryTask, Query, PopupTemplate, arrayUtils, dom, on
) {

  //URL to feature service containing points representing the 50 
  //most prominent peaks in the U.S. 
  var peaksUrl = "http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Prominent_Peaks_US/FeatureServer/0";

  //Define the popup content for each result    
  var popupTemplate = new PopupTemplate({
    title: "{MTN_PEAK}, {STATE}",
    fieldInfos: [{
      fieldName: "ELEV_ft",
      label: "Elevation (feet)",
      format: {
        places: 0,
        digitSeperator: true
      }
    }, {
      fieldName: "ELEV_m",
      label: "Elevation (meters)",
      format: {
        places: 0,
        digitSeperator: true
      }
    }, {
      fieldName: "PROMINENCE_ft",
      label: "Prominence (feet)",
      format: {
        places: 0,
        digitSeperator: true
      }
    }, {
      fieldName: "PROMINENCE_m",
      label: "Prominence (meters)",
      format: {
        places: 0,
        digitSeperator: true
      }
    }, {
      fieldName: "ISOLATION_mi",
      label: "Isolation (miles)",
      format: {
        places: 0,
        digitSeperator: true
      }
    }, {
      fieldName: "ISOLATION_km",
      label: "Isolation (km)",
      format: {
        places: 0,
        digitSeperator: true
      }
    }],
    content: "<b><a href='https://en.wikipedia.org/wiki/Topographic_prominence'>Prominence:</a>" +
      "</b> {PROMINENCE_ft} ft ({PROMINENCE_m} m)" +
      "<br><b>Prominence Rank:</b> {RANK}" +
      "<br><b>Elevation:</b> {ELEV_ft} ft ({ELEV_m} m)" +
      "<br><b><a href='https://en.wikipedia.org/wiki/Topographic_isolation'>Isolation:</a>" +
      "</b> {ISOLATION_mi} mi ({ISOLATION_km} km)"
  });

  //Create graphics layer and symbol to use for displaying the results of query    
  var resultsLyr = new GraphicsLayer();
  var resultSym = new SimpleMarkerSymbol({
    color: [0, 82, 26],
    size: 12,
    style: "diamond",
    outline: new SimpleLineSymbol({
      color: [80, 128, 95, 0.5],
      style: "solid",
      width: 4
    })
  });

  /*****************************************************************
  *  Point QueryTask to URL of feature service  
  *****************************************************************/
  qTask = new QueryTask({
    url: peaksUrl
  });

  /******************************************************************    
  * Set the query parameters to always return geometry and all fields.
  * Returning geometry allows us to display results on the map/view
  ******************************************************************/
  params = new Query({
    returnGeometry: true,
    outFields: ["*"]
  });

  map = new Map({
    basemap: "oceans",
    layers: [resultsLyr] //add graphics layer to the map
  });

  view = new SceneView({
    map: map,
    container: "viewDiv",
    center: [-100, 38],
    zoom: 4
  });

  var attributeName = dom.byId("attSelect");
  var expressionSign = dom.byId("signSelect");
  var value = dom.byId("valSelect");

  //Executes each time the button is clicked    
  function doQuery() {
    //Clear the results from a previous query
    resultsLyr.clear();
    /*********************************************
     *
     * Set the where clause for the query. This can be any valid SQL expression.
     * In this case the inputs from the three drop down menus are used to build
     * the query. For example, if "Elevation", "is greater than", and "10,000 ft" 
     * are selected, then the following SQL where clause is built here:
     * 
     * params.where = "ELEV_ft > 10000";  
     * 
     * ELEV_ft is the field name for Elevation and is assigned to the value of the
     * select option in the HTML below. Other operators such as AND, OR, LIKE, etc
     * may also be used here.
     *
     **********************************************/
    params.where = attributeName.value + expressionSign.value + value.value;

    //executes the query and calls getResults() once the promise is resolved
    //promiseRejected() is called if the promise is rejected
    qTask.execute(params).then(getResults, promiseRejected);
  }

  //Called each time the promise is resolved    
  function getResults(response) {
    //Loop through each of the results and assign a symbol and PopupTemplate 
    //to each so they may be visualized on the map
    var peakResults = arrayUtils.map(response.features, function(
      feature) {
//      feature.symbol = resultSym;
      feature.symbol = new PointSymbol3D({
        symbolLayers: [new ObjectSymbol3DLayer({
          material: {
            color: "green"
          },
          resource: {
            primitive: "cone"
          },
          width: 100000,
          height: feature.attributes.ELEV_m * 100
        })]  
      });
      feature.popupTemplate = popupTemplate;
      return feature;
    });
    resultsLyr.add(peakResults);
    //animate to the results after they are added to the map  
    view.animateTo(peakResults);
    //print the number of results returned to the user
    dom.byId("printResults").innerHTML = peakResults.length +
      " results found!";
  }

  //Called each time the promise is rejected    
  function promiseRejected(err) {
    console.error("Promise rejected: ", err.message);
  }

  //Call doQuery() each time the button is clicked    
  on(dom.byId("doBtn"), "click", doQuery);
});
</script>
</head>

<body>
  <div id="viewDiv"></div>
  <div id="optionsDiv">
    <h2>Prominent Peaks in the U.S.</h2>
    <select id="attSelect">
      <option value="ELEV_ft">Elevation</option>
      <option value="PROMINENCE_ft" selected>Prominence</option>
    </select>
    <select id="signSelect">
      <option value=">">is greater than</option>
      <option value="<">is less than</option>
      <option value="=">is equal to</option>
    </select>
    <select id="valSelect">
      <option value="1000">1,000 ft</option>
      <option value="5000">5,000 ft</option>
      <option value="10000">10,000 ft</option>
      <option value="15000">15,000 ft</option>
      <option value="20000">20,000 ft</option>
      <option value="PROMINENCE_ft">Prominence</option>
    </select>
    <br>
    <br>
    <button id="doBtn">Do Query</button>
    <br>
    <p><span id="printResults"></span></p>
  </div>
</body>

</html>